perm filename OBJFTP.SAI[11,HE] blob
sn#651176 filedate 1982-04-01 generic text, type T, neo UTF8
BEGIN "FTP Program Image mode only 10→11" comment OBJFTP.SAI;
COMMENT For variable-length files such as .OBJ files, which have been read
from tape using COPY, where the tape is in industry-compatible mode
(ANSI-labelled format).
It changes the ASCII record length which appears at the beginning
of each record into what RSX wants, which is a single word record
length indicator. Other than that, just like IFTP.SAI;
DEFINE CRLF="('15&'12)",
CR ="'15",
LF ="'12",
! = "COMMENT ",
TIL="STEP 1 UNTIL";
REQUIRE "11UTIL.HDR[11,SYS]" SOURCE_FILE;
DEFINE TTYSET = "'047000400121";
DEFINE GETLIN = "'051300000000";
INTEGER chan; ! Channel number for I/O to RSX;
INTEGER dskchan; ! Channel number for 10 disk I/O;
EXTERNAL INTEGER _SKIP_;
INTEGER ARRAY inbuffer[1:256], outbuffer[1:256];
INTEGER endbuf;
INTEGER talk10,char,i,j,k,l,brk,dum,eof,base,bufadr,bufptr;
INTEGER outptr, inptr;
STRING s,f1,fnam10,fext10,ppn10;
LABEL fin;
PROCEDURE parse10 (STRING s);
BEGIN
fnam10 ← fext10 ← NULL;
WHILE s=" " ∧ s ≠ NULL DO dum ← LOP(s); ! Strip off leading blanks;
WHILE s≠"." ∧ s≠"[" ∧ s≠NULL DO fnam10 ← fnam10 & LOP(s); ! Build up file name;
WHILE s≠"[" ∧ s≠NULL DO fext10 ← fext10 & LOP(s); ! Build up file extension;
IF s="[" THEN ppn10 ← s; ! Set ppn if present;
END;
PROCEDURE SENDBUFFER;
BEGIN
WHILE (bufadr←PEEK(bufptr))=0 DO CALL(0,"SLEEP"); ! Sleep for 1 tick;
IF bufadr LAND 1 THEN ! Something's wrong - abort;
BEGIN
PRINT("Error while writing file"&crlf);
GO TO fin;
END;
bufadr ← bufadr + base;
POKEARRAY(bufadr,256,outbuffer,0); ! Transfer the sector over;
POKE(bufptr,0); ! Tell 11 to write it out;
outptr ← 1; ! Reset output buffer pointer;
END;
PROCEDURE FILLBUFFER;
BEGIN
INTEGER i,j,k,b1,b2,b3,b4,word1,word2;
print (crlf,"[fillbuffer...]",crlf);
FOR i:=1 STEP 2 UNTIL 255 DO begin
k ← WORDIN(dskchan); ! Get next 2 words from file;
j ← POINT(8,k,7);
b1←ldb(j); b2←ildb(j); b3←ildb(j); b4←ildb(j); ! retreive bytes;
word1 ← b1 + (b2 LSH 8); ! First word;
word2 ← b3 + (b4 LSH 8); ! Second word;
inbuffer[i] ← word1; ! Store 1st word;
inbuffer[i+1] ← word2;
end;
inptr ← 1; ! Reset in-buffer pointer;
END;
INTEGER PROCEDURE NEXTWORD;
BEGIN
INTEGER I;
IF INPTR>256 THEN FILLBUFFER; ! And reset INPTR to 1;
I ← INBUFFER[INPTR];
INPTR ← INPTR + 1;
! PRINT("[NextWord:",cvos(i),"]");
RETURN (I);
END;
PROCEDURE WRITEWORD (INTEGER W);
BEGIN
! PRINT("[WriteWord(",w,") ]");
OUTBUFFER[OUTPTR] ← W;
OUTPTR ← OUTPTR + 1;
IF OUTPTR>256 THEN SENDBUFFER; ! And reset outptr to 1;
END;
! START HERE;
SETBREAK(1,crlf,NULL,"INS");
ALINIT(false); ! Assign the ELF, but don't care about ARM;
PRINT(crlf & "10-11 FTP Program"&crlf&crlf);
print ("** This version does object file conversions!! **",crlf);
chan ← GETCHAN;
OPEN(chan,"TTY53",0,1,1,999,brk,dum);
QUICK_CODE
LABEL XIT,SETUP;
HRRI '13,SETUP; ! Command list to initialize the tty;
HRLI '13,-3; ! Number of commands;
TTYSET '13,0; ! Do it;
JRST XIT;
SETUP:
! '072453000001; ! Set TTY EXIST;
! '040453000005; ! Set tty speed = 1200 baud;
'001453000004; ! Set (XON &) NO ECHO;
'002453010000; ! Set TTY NO ARROW?;
'023453000001; ! Set TTY GAG;
XIT: END;
OUT(chan,"RUN OBJFTP/CKP=NO"&crlf);
WHILE INPUT(chan,1) = NULL DO ; ! Ignore echo from RSX;
WHILE (s←INPUT(chan,1)) = NULL ∨ s=">" DO ;
base ← CVO(s) LSH 6; ! Get address of Partition Base;
PRINT("Partition base = ",CVOS(base),crlf);
WHILE (s←INPUT(chan,1)) = NULL DO ;
bufptr ← CVO(s); ! Get address of buffer pointer;
PRINT("Buffer pointer = ",CVOS(bufptr),crlf);
bufptr ← base + bufptr;
dskchan ← GETCHAN;
OPEN(dskchan,"DSK",'10,19,0,0,0,eof);
WHILE TRUE DO ! Get file to ship over;
BEGIN
PRINT("*");
f1 ← INCHWL; ! Read file name;
IF f1 = NULL THEN
BEGIN
POKE(bufptr+4,0); ! Tell 11 we're finished;
CALL(0,"EXIT");
END;
PARSE10(f1);
LOOKUP(dskchan,fnam10 & fext10 & ppn10,i);
IF i THEN
BEGIN PRINT("ABORTED - Can't find:",fnam10,fext10,ppn10,crlf); GO TO fin END;
POKE(bufptr+2,1); ! Tell 11 we're ready to start;
eof ← FALSE;
FillBuffer; ! Fill 1st input buffer (128 words from 11);
outptr ← 1; ! First location to fill in output buffer;
DO BEGIN ! Start transferring characters to the 11;
INTEGER bb1,bb2,len,jj,eor;
j ← nextword; ! Figure out record length;
bb1 ← (j LAND '377)-'60; ! Low byte, convert ascii to integer;
bb2 ← ((j LSH -8) LAND '377)-'60; ! and high byte;
if j = '57136 then begin ! End of record...ignore the rest;
! print(crlf,"End of buffer. Words we ignore: ");
! for jj←inptr TIL 256 do print(cvos(inbuffer[jj])," ");
! print(crlf);
FillBuffer; ! So ignore the rest of this buffer;
j ← NextWord; ! Re-get 1st word;
bb1 ← (j LAND '377)-'60; ! and re-do byte getting;
bb2 ← ((j LSH -8) LAND '377)-'60;
end;
len ← (bb1 * 10) + bb2;
j ← nextword;
bb1 ← (j LAND '377)-'60; ! Low byte, convert ascii to integer;
bb2 ← ((j LSH -8) LAND '377)-'60; ! and high byte;
len ← (len * 100) + (bb1 * 10) + bb2;
! print (crlf,"[ Length=",len,"] ",crlf);
len ← len - 4; ! Account for offset;
writeword (len); ! Write record length;
len ← len DIV 2; ! Bytes => words;
for jj ← 1 TIL len do begin ! Read rest of record;
j ← nextword; ! Get next word;
writeword(j); ! Store 1st word;
end;
END
UNTIL eof;
IF outptr<=256 then sendbuffer; ! Send remaining words, if any;
POKE(bufptr+2,0); ! Tell 11 we're all done;
fin:
CLOSE(dskchan);
END;
END;